#include "mytcpsocket.h"
#include <QDebug>
#include <stdio.h>
#include "mytcpserver.h"
#include <QDir> //包含了所有对文件夹的操作
#include <QFileInfoList>
#include <QByteArray>

MyTcpSocket::MyTcpSocket()
{
    ///客户端连接时，获取信息，并发送处理结果
    connect(this,SIGNAL(readyRead()),this,SLOT(recvMsg()));

    ///客户端下线时，处理账户信息
    connect(this,SIGNAL(disconnected()),this,SLOT(clientOffline()));

    m_bUploadt=false;
    m_pTimer=new QTimer;
    connect(m_pTimer,SIGNAL(timeout()),this,SLOT(sendFileToClient()));
}

QString MyTcpSocket::getName()
{
    return m_strName;
}

void MyTcpSocket::recvMsg()
{
    //如果不是上传文件的状态，按照PDU进行接收
    if(!m_bUploadt){
        qDebug()<<this->bytesAvailable();   //输出数据总长12+64+x
        uint uiPUDLen=0;
        this->read((char*)&uiPUDLen,sizeof(uint));  //获取uiPDULen
        uint uiMsgLen=uiPUDLen-sizeof(PDU); //解析实际动态数组的长度
        PDU *pdu=mkPDU(uiMsgLen); //为PDU开辟空间
        this->read((char*)pdu+sizeof (uint),uiPUDLen-sizeof(uint));  //接收剩余信息并填充
    //    qDebug()<<pdu->uiMsgType<<(char*)(pdu->caMsg);  //输出传来的uiMsgType，还有数据
        //判断消息类型
        switch (pdu->uiMsgType) {
            //查看用户信息里是否重复
        case ENUM_MSG_TYPE_REGIST_REQUEST:{
            char caName[32] = {'\0'};
            char caPwd[32] = {'\0'};
            strncpy(caName, pdu->caData, 32);
            strncpy(caPwd, pdu->caData+32, 32);
            bool ret = OpeDB::getInstance().handleRegist(caName, caPwd); //在数据库中注册
            PDU *respdu = mkPDU(0); //回复的消息使用caData已经够用，消息长度可为0
            respdu->uiMsgType = ENUM_MSG_TYPE_REGIST_RESPOND;
            if(ret){
                strcpy(respdu->caData,REGIST_OK);
                QDir dir;
                //指定目录创建用户文件夹  (服务器debug目录中创建tom ./XXX)
                QString str1="D:/work/demo/demo1-v1/book/";
                QString str2=QString("%1").arg(caName);
                qDebug()<<"create dir: "<<dir.mkdir(str1.append(str2));
            }
            else{
                strcpy(respdu->caData,REGIST_FAILED);
            }
            write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
            free(respdu);
            respdu=NULL;

            break;
        }
            //查看用户信息里是否有信息，及是否登录过
        case ENUM_MSG_TYPE_LOGIN_REQUEST:{
            char caName[32] = {'\0'};
            char caPwd[32] = {'\0'};
            strncpy(caName, pdu->caData, 32);
            strncpy(caPwd, pdu->caData+32, 32);
            bool ret = OpeDB::getInstance().handleLogin(caName, caPwd);
            PDU *respdu = mkPDU(0); //回复的消息使用caData已经够用，消息长度可为0
            respdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_RESPOND;
            if(ret){
                strcpy(respdu->caData,LOGIN_OK);
                m_strName=caName;   //登录成功时,记录客户端名字
            }
            else{
                strcpy(respdu->caData,LOGIN_FAILED);
            }
            write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
            free(respdu);
            respdu=NULL;

            break;
        }
            //查找在线用户姓名
        case ENUM_MSG_TYPE_ALL_ONLINE_REQUEST:{
            QStringList ret=OpeDB::getInstance().handleAllOnline();
            //装填查询的用户信息
            uint uiMsgLen=ret.size()*32;
            PDU *respdu=mkPDU(uiMsgLen);
            respdu->uiMsgType = ENUM_MSG_TYPE_ALL_ONLINE_RESPOND;
            for(int i=0;i<ret.size();i++){
                //pdu中位置，数据，数据长度
                memcpy((char*)respdu->caMsg+i*32,
                       ret.at(i).toStdString().c_str(),
                       ret.at(i).size());
            }
            write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
            free(respdu);
            respdu=NULL;

            break;
        }
            //搜索用户信息
        case ENUM_MSG_TYPE_SEARCH_USR_REQUEST:{
            int ret=OpeDB::getInstance().handleSearchUsr(pdu->caData);
            PDU *respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_SEARCH_USR_RESPOND;
            if(ret==-1){
                //找不到此用户
                strcpy(respdu->caData,SEARCH_USR_NO);
            }
            else if(ret==1){
                //用户已下线
                strcpy(respdu->caData,SEARCH_USR_ONLINE);
            }
            else if(ret==0){
                //用户在线
                strcpy(respdu->caData,SEARCH_USR_OFFLINE);
            }
            write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
            free(respdu);
            respdu=NULL;
            break;
        }
            //添加好友申请
        case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:{
            char caPerName[32] = {'\0'};
            char caName[32] = {'\0'};
            strncpy(caPerName, pdu->caData, 32);
            strncpy(caName, pdu->caData+32, 32);
            int ret=OpeDB::getInstance().handleAddFriend(caPerName,caName);
            //qDebug()<<"ret="<<ret;    测试ret返回结果
            PDU *respdu=NULL;
            if(ret==-1){
                //信息出错
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
                strcpy(respdu->caData,UNKNOW_ERROR);
                write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
                free(respdu);
                respdu=NULL;
            }
            else if(ret==0){
                //已经是好友
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
                strcpy(respdu->caData,EXISTED_FRIEND);
                write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
                free(respdu);
                respdu=NULL;
            }
            else if(ret==1){
                //对方在线，可向其申请好友
                MyTcpServer::getInstance().resend(caPerName,pdu);
                //消息类型仍然是ENUM_MSG_TYPE_ADD_FRIEND_REQUEST
            }
            else if(ret==2){
                //对方已离线
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
                strcpy(respdu->caData,ADD_FRIEND_OFFLINE);
                write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
                free(respdu);
                respdu=NULL;
            }
            else if(ret==3){
                //对方不存在
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
                strcpy(respdu->caData,ADD_FRIEND_NOEXIST);
                write((char*)respdu,respdu->uiPDULen);    //利用Tcp协议发送数据
                free(respdu);
                respdu=NULL;
            }
            break;
        }
            //对方同意加好友
        case ENUM_MSG_TYPE_ADD_FRIEND_AGREE:
        {
            char caPerName[32] = {'\0'};
            char caName[32] = {'\0'};
            strncpy(caPerName, pdu->caData, 32);
            strncpy(caName, pdu->caData+32, 32);
            //在数据库更新好友关系 对方 请求者
            OpeDB::getInstance().handleAgreeAddFriend(caPerName, caName);
            //转发回复请求者
            MyTcpServer::getInstance().resend(caName, pdu);
            break;
        }
            //对方不同意加好友
        case ENUM_MSG_TYPE_ADD_FRIEND_REFUSE:
        {
            char caName[32] = {'\0'};
            strncpy(caName, pdu->caData+32, 32);
            //转发回复请求者
            MyTcpServer::getInstance().resend(caName, pdu);
            break;
        }
            //刷新好友请求
        case ENUM_MSG_TYPE_FLUSH_FRIEND_REQUEST:{
            char caName[32] = {'\0'};
            strncpy(caName, pdu->caData, 32);
            //已发送用户名 调用函数检查好友关系
            QStringList ret = OpeDB::getInstance().handleFlushFriend(caName);
            //根据好友数添加消息
            uint uiMsgLen = ret.size()*32;
            PDU *respdu = mkPDU(uiMsgLen);
            respdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FRIEND_RESPOND;
            //考虑到数据的偏移量，转换成char*进行数据拷贝
            for (int i=0; i<ret.size(); i++)
            {
                memcpy((char*)(respdu->caMsg)+i*32
                       , ret.at(i).toStdString().c_str()
                       , ret.at(i).size());
            }
            //数据发送至客户端
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu = NULL;
            break;
        }
            //删除好友请求
        case ENUM_MSG_TYPE_DELETE_FRIEND_REQUEST:{
            char caSelfName[32] = {'\0'};
            char caFriendName[32] = {'\0'};
            strncpy(caSelfName, pdu->caData, 32);
            strncpy(caFriendName, pdu->caData+32, 32);
            OpeDB::getInstance().handleDelFriend(caFriendName,caSelfName);

            //回复操作方  对方在线则发送消息提示，反之不对其消息提示
            PDU *respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_DELETE_FRIEND_RESPOND;
            strcpy(respdu->caData,DEL_FRIEND_OK);
            write((char*)respdu, respdu->uiPDULen);
            qDebug()<<"开始回复";
            free(respdu);
            respdu = NULL;

            MyTcpServer::getInstance().resend(caFriendName,pdu);

            break;
        }
            //私聊请求
        case ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST:{
            //找到对方的socket转发信息
            char caChatName[32] = {'\0'};
            strncpy(caChatName, pdu->caData+32, 32);
            qDebug()<<caChatName;   //测试
            MyTcpServer::getInstance().resend(caChatName,pdu);

            break;
        }
            //群聊请求
        case ENUM_MSG_TYPE_GROUP_CHAT_REQUEST:{
            char caName[32] = {'\0'};
            strncpy(caName, pdu->caData, 32);
            QStringList onlineFriend = OpeDB::getInstance().handleFlushFriend(caName);
            for(int i=0;i<onlineFriend.size();i++){
                MyTcpServer::getInstance().resend(onlineFriend.at(i).toStdString().c_str(),pdu);
            }
            break;
        }
            //创建目录请求
        case ENUM_MSG_TYPE_CREATE_DIR_REQUEST:{
            QDir dir;
            QString strCurPath=QString("%1").arg((char*)(pdu->caMsg));
            bool ret=dir.exists(strCurPath);
            PDU *respdu=NULL;
            if(ret){    //当前目录存在
                char caNewDir[32]={'\0'};
                memcpy(caNewDir,pdu->caData+32,32);
                QString strNewPath=strCurPath+"/"+caNewDir;
                qDebug()<<strNewPath;
                ret=dir.exists(strNewPath);
                //文件已存在
                if(ret){
                    respdu=mkPDU(0);
                    respdu->uiMsgType=ENUM_MSG_TYPE_CREATE_DIR_RESPOND;
                    strcpy(respdu->caData,FILE_NAME_EXIST);
                }
                //文件不存在
                else{
                    dir.mkdir(strNewPath);
                    respdu=mkPDU(0);
                    respdu->uiMsgType=ENUM_MSG_TYPE_CREATE_DIR_RESPOND;
                    strcpy(respdu->caData,CREATE_DIR_OK);
                }
            }
            else{   //当前目录不存在
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_CREATE_DIR_RESPOND;
                strcpy(respdu->caData,DIR_NO_EXIST);
            }
            write((char*)respdu, respdu->uiPDULen);
            break;
        }
            //刷新文件请求
        case ENUM_MSG_TYPE_FLUSH_FILE_REQUEST:{
            //获取发送的路径
            char *pCurPath=new char[pdu->uiMsgLen];
            memcpy(pCurPath,pdu->caMsg,pdu->uiMsgLen);
            QDir dir(pCurPath);
            //获取文件列表
            QFileInfoList fileInfoList=dir.entryInfoList();
            int iFileCount=fileInfoList.size();
            //拷贝信息至PDU
            PDU *respdu=mkPDU(sizeof(FileInfo)*iFileCount);
            respdu->uiMsgType=ENUM_MSG_TYPE_FLUSH_FILE_RESPOND;
            FileInfo *pFileInfo=NULL;
            QString strFileName;
            for(int i=0;i<iFileCount;i++){
    //            if(QString(".")==fileInfoList[i].fileName()||QString("..")==fileInfoList[i].fileName()){
    //                continue;
    //            }
                //由指针地址填充数据，填充到PDU
                pFileInfo=(FileInfo*)(respdu->caMsg)+i;
                strFileName=fileInfoList[i].fileName();
                memcpy(pFileInfo->caFileName,strFileName.toStdString().c_str(),strFileName.size());

                if(fileInfoList[i].isDir()){
                    pFileInfo->iFileType=0; //0表示一个文件夹
                }
                else if(fileInfoList[i].isFile()){
                    pFileInfo->iFileType=1; //1表示一个文件
                }
                qDebug()<<fileInfoList[i].fileName()
                       <<fileInfoList[i].size()
                      <<"文件夹:"<<fileInfoList[i].isDir()
                     <<"常规文件:"<<fileInfoList[i].isFile();
            }
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;
            break;
        }
            //删除文件请求
        case ENUM_MSG_TYPE_DEL_DIR_REQUEST:{
            //拼接路径
            char caName[32]={'\0'};
            strcpy(caName,pdu->caData);
            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);
            QString strPath=QString("%1/%2").arg(pPath).arg(caName);
            qDebug()<<strPath;

            QFileInfo fileInfo(strPath);
            bool ret=false;
            if(fileInfo.isDir()){   //删除目录
                QDir dir;
                dir.setPath(strPath);
                //删除文件夹及内部文件
                ret=dir.removeRecursively();
            }
            else if(fileInfo.isFile()){ //常规文件
                ret=false;
            }
            PDU *respdu=NULL;
            if(ret){
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_DEL_DIR_RESPOND;
                memcpy(respdu->caData,DEL_DIR_OK,strlen(DEL_DIR_OK));
            }
            else{
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_DEL_DIR_RESPOND;
                memcpy(respdu->caData,MOVE_FILE_FAILURED,strlen(MOVE_FILE_FAILURED));
            }
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;
            break;
        }
            //重命名文件请求
        case ENUM_MSG_TYPE_RENAME_FILE_REQUEST:{
            char caOldName[32]={'\0'};
            char caNewName[32]={'\0'};
            strncpy(caOldName,pdu->caData,32);
            strncpy(caNewName,pdu->caData+32,32);

            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);

            QString strOldPath=QString("%1/%2").arg(pPath).arg(caOldName);
            QString strNewPath=QString("%1/%2").arg(pPath).arg(caNewName);

            qDebug()<<strOldPath;
            qDebug()<<strNewPath;

            QDir dir;
            bool ret=dir.rename(strOldPath,strNewPath);
            PDU *respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_RENAME_FILE_RESPOND;
            if(ret){
                //memcpy(respdu->caData,RENAME_FILE_OK,strlen(RENAME_FILE_OK));
                strcpy(respdu->caData,RENAME_FILE_OK);
            }
            else{
                strcpy(respdu->caData,RENAME_FILE_FAILURED);
            }
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;
            break;
        }
            //进入文件目录请求
        case ENUM_MSG_TYPE_ENTER_DIR_REQUEST:{
            //获取要进入的文件夹位置
            char caEnterName[32]={'\0'};
            strncpy(caEnterName,pdu->caData,32);

            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);

            QString strPath=QString("%1/%2").arg(pPath).arg(caEnterName);

            QFileInfo fileInfo(strPath);
            PDU *respdu=NULL;
            //根据能否进入,反馈消息
            if(fileInfo.isDir()){
                QDir dir(strPath);
                QFileInfoList fileInfoList = dir.entryInfoList();
                int iFileCount = fileInfoList.size();
                respdu = mkPDU(sizeof(FileInfo)*iFileCount);
                //若可进，发送刷新的请求
                respdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FILE_RESPOND;
                FileInfo *pFileInfo = NULL;
                QString strFileName;
                for (int i=0; i<iFileCount; i++)
                {
                    pFileInfo = (FileInfo*)(respdu->caMsg)+i;
                    strFileName = fileInfoList[i].fileName();

                    memcpy(pFileInfo->caFileName, strFileName.toStdString().c_str(), strFileName.size());
                    if (fileInfoList[i].isDir())
                    {
                        pFileInfo->iFileType = 0;
                    }
                    else if (fileInfoList[i].isFile())
                    {
                        pFileInfo->iFileType = 1;
                    }
                }
                write((char*)respdu, respdu->uiPDULen);
                free(respdu);
                respdu = NULL;
            }
            //若不可进，返回消息
            else if(fileInfo.isFile()){
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_ENTER_DIR_RESPOND;
                strcpy(respdu->caData,ENTER_DIR_FAILURED);

                write((char*)respdu,respdu->uiPDULen);
                free(respdu);
                respdu=NULL;
            }
            break;
        }
            //上传文件请求
        case ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST:{
            //文件名、大小 及路径解析
            char caFileName[32]={'\0'};
            qint64 fileSize=0;
            sscanf(pdu->caData,"%s %lld",caFileName,&fileSize);
            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);
            QString strPath=QString("%1/%2").arg(pPath).arg(caFileName);
            qDebug()<<strPath;
            delete []pPath;
            pPath=NULL;

            m_file.setFileName(strPath);
            //以只写的方式打开文件，若文件不存在，则会自动创建文件
            if(m_file.open(QIODevice::WriteOnly)){
                //可考虑多线程，此处预处理信息
                m_bUploadt=true;
                m_iTotal=fileSize;
                m_iRecved=0;
            }

            break;
        }
            //删除文件的请求
        case ENUM_MSG_TYPE_DEL_FILE_REQUEST:{
            //拼接路径
            char caName[32]={'\0'};
            strcpy(caName,pdu->caData);
            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);
            QString strPath=QString("%1/%2").arg(pPath).arg(caName);
            qDebug()<<strPath;

            QFileInfo fileInfo(strPath);
            bool ret=false;
            if(fileInfo.isDir()){   //目录
                ret=false;
            }
            else if(fileInfo.isFile()){ //删除常规文件
                QDir dir;
                dir.setPath(strPath);
                //删除文件
                ret=dir.remove(strPath);
                qDebug()<<ret;
            }
            PDU *respdu=NULL;
            if(ret){
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_DEL_DIR_RESPOND;
                memcpy(respdu->caData,DEL_FILE_OK,strlen(DEL_FILE_OK));
            }
            else{
                respdu=mkPDU(0);
                respdu->uiMsgType=ENUM_MSG_TYPE_DEL_DIR_RESPOND;
                memcpy(respdu->caData,DEL_FILE_FAILURED,strlen(DEL_FILE_FAILURED));
            }
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;
            break;
            break;
        }
            //下载文件的请求 告知目标文件名和大小
        case ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST:{
            //目标位置文件名、大小 及路径解析
            char caFileName[32]={'\0'};
            strcpy(caFileName,pdu->caData);
            char *pPath=new char[pdu->uiMsgLen];
            memcpy(pPath,pdu->caMsg,pdu->uiMsgLen);
            QString strPath=QString("%1/%2").arg(pPath).arg(caFileName);
            qDebug()<<strPath;
            delete []pPath;
            pPath=NULL;

            //发送大小
            QFileInfo fileInfo(strPath);
            qint64 fileSize=fileInfo.size();
            PDU *respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND;
            //caData放置文件名，大小
            sprintf(respdu->caData,"%s %lld",caFileName,fileSize);
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;

            m_file.setFileName(strPath);
            m_file.open(QIODevice::ReadOnly);
            m_pTimer->start(1000);

            break;
        }
            //分享文件的请求
        case ENUM_MSG_TYPE_SHARE_FILE_REQUEST:{
            char caSendName[32]={'\0'};
            int num=0;
            sscanf(pdu->caData,"%s %d",caSendName,&num);
            int size=num*32;
            //按照路径所占的空间设置PDU
            PDU *respdu=mkPDU(pdu->uiMsgLen-size);
            respdu->uiMsgType=ENUM_MSG_TYPE_SHARE_FILE_NOTE;
            //分享者
            strcpy(respdu->caData,caSendName);
            //文件路径信息
            memcpy((char*)respdu->caMsg,(char*)(pdu->caMsg)+size,pdu->uiMsgLen-size);

            //根据名字转发给不同用户
            char caRecvName[32]={'\0'};
            for(int i=0;i<num;i++){
                memcpy(caRecvName,(char*)(pdu->caMsg)+i*32,32);
                MyTcpServer::getInstance().resend(caRecvName,respdu);
            }
            free(respdu);
            respdu=NULL;

            //回复已发送
            respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_SHARE_FILE_RESPOND;
            strcpy(respdu->caData,"share file ok");
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;
            break;
        }
            //客户端回复用户是否接受分享后
        case ENUM_MSG_TYPE_SHARE_FILE_NOTE_RESPOND:{
            //默认拷贝到接受者目录
            QString str1="D:/work/demo/demo1-v1/book/";
            QString str2=QString("%1").arg(pdu->caData);
            QString strRecvPath=str1.append(str2);
            //提取发送者目录
            QString strShareFilePath=QString("%1").arg((char*)pdu->caMsg);
            //构造新文件位置
            int index=strShareFilePath.lastIndexOf('/');
            QString strFileName=strShareFilePath.right(strShareFilePath.size()-index-1);
            strRecvPath=strRecvPath+'/'+strFileName;

            //判断常规文件还是文件夹
            QFileInfo fileInfo(strShareFilePath);   //转换成文件信息
            if(fileInfo.isFile()){
                //常规文件直接拷贝
                QFile::copy(strShareFilePath,strRecvPath);
            }
            else if(fileInfo.isDir()){
                copyDir(strShareFilePath,strRecvPath);
            }
            break;
        }
            //移动文件请求
        case ENUM_MSG_TYPE_MOVE_FILE_REQUEST:{
            char caFileName[32]={'\0'};
            int srcLen=0;
            int destLen=0;
            sscanf(pdu->caData,"%d %d %s",&srcLen,&destLen,caFileName);
            char *pSrcPath=new char[srcLen+1];
            //最终的文件位置 32用于拼接文件名
            char *pDestPath=new char[destLen+1+32];
            //获取路径信息
            memset(pSrcPath,'\0',srcLen+1);
            memset(pDestPath,'\0',destLen+1+32);

            memcpy(pSrcPath,pdu->caMsg,srcLen);
            memcpy(pDestPath,(char*)(pdu->caMsg)+srcLen+1,destLen);

            PDU *respdu=mkPDU(0);
            respdu->uiMsgType=ENUM_MSG_TYPE_MOVE_FILE_RESPOND;
            QFileInfo fileInfo(pDestPath);
            //判断是否为文件夹
            if(fileInfo.isDir()){
                strcat(pDestPath,"/");
                strcat(pDestPath,caFileName);
                //文件移动
                bool ret=QFile::rename(pSrcPath,pDestPath);
                if(ret){
                    strcpy(respdu->caData,MOVE_FILE_OK);
                }
                else{
                    strcpy(respdu->caData,COMMON_ERR);
                }
            }
            else if(fileInfo.isFile()){
                strcpy(respdu->caData,MOVE_FILE_FAILURED);
            }
            write((char*)respdu,respdu->uiPDULen);
            free(respdu);
            respdu=NULL;

            break;
        }
        default:
            break;
        }
        free(pdu);
        pdu=NULL;
    }
    else{
        //以二进制的形式接收数据
        QByteArray buff=readAll();  //返回字节数组
        m_file.write(buff);
        m_iRecved+=buff.size();
        PDU *respdu=mkPDU(0);
        respdu->uiMsgType=ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;
        if(m_iTotal==m_iRecved){
            m_file.close();
            m_bUploadt=false;

            strcpy(respdu->caData,UPLOAD_FILE_OK);
            //用于收完数据直接回复
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu = NULL;
        }
        else if(m_iTotal<m_iRecved){
            m_file.close();
            m_bUploadt=false;

            strcpy(respdu->caData,UPLOAD_FILE_FAILURED);
            write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu = NULL;
        }

    }
}

void MyTcpSocket::clientOffline()
{
    OpeDB::getInstance().handleOffline(m_strName.toStdString().c_str());    //数据库更新
    //****
    qDebug()<<m_strName.toStdString().c_str();
    emit offline(this); //发送信号到MyTcpServer
}

void MyTcpSocket::sendFileToClient(){
    m_pTimer->stop();
    char *pData=new char[4096];
    qint64 ret=0;
    while (true) {
        ret=m_file.read(pData,4096);
        if(ret>0&&ret<=4096){
            write(pData,ret);
        }
        else if(ret==0){
            m_file.close();
            break;
        }
        else if(ret<0){
            qDebug()<<"发送文件内容给客户端过程中失败";
            m_file.close();
            break;
        }
    }
    delete []pData;
    pData=0;
}

void MyTcpSocket::copyDir(QString strSrcDir,QString strDestDir){
    QDir dir;
    dir.mkdir(strDestDir);

    dir.setPath(strSrcDir);
    QFileInfoList fileInfoList=dir.entryInfoList();

    QString srcTmp;
    QString destTmp;
    for(int i=0;i<fileInfoList.size();i++){
        qDebug()<<"fileName: "<<fileInfoList[i].fileName();
        if(fileInfoList[i].isFile()){
            //原文件位置 新文件位置
            srcTmp=strSrcDir+'/'+fileInfoList[i].fileName();
            destTmp=strDestDir+'/'+fileInfoList[i].fileName();
            QFile::copy(srcTmp,destTmp);
        }
        else if(fileInfoList[i].isDir()){
            if(QString(".")==fileInfoList[i].fileName()||QString("..")==fileInfoList[i].fileName()){
                continue;
            }
            srcTmp=strSrcDir+'/'+fileInfoList[i].fileName();
            destTmp=strDestDir+'/'+fileInfoList[i].fileName();
            copyDir(srcTmp,destTmp);
        }
    }
}
